_package("alz.core");

_import("alz.LibContext");
_import("alz.core.EventTarget");
_import("alz.core.ScriptLoader");
_import("alz.core.PluginManager");
_import("alz.core.AjaxEngine");
_import("alz.core.AppManager");
_import("alz.core.Element");
_import("alz.core.XPathQuery");
_import("alz.core.AnimationEngine");
_import("alz.core.ThreadPool");
_import("alz.core.TaskSchedule");
_import("alz.core.EventManager");
_import("alz.gesture.GestureManager");
_import("caf.CloudApi");

/**
 * WebApp运行时环境
 */
_class("WebRuntime", EventTarget, function(){
	var PLUGINS_CONF_0 = [  //插件配置列表
		{"id": "thread"        , "clazz": "ThreadPool"     },  //伪线程池
		{"id": "task"          , "clazz": "TaskSchedule"   }   //任务调度器
	];
	var PLUGINS_CONF_1 = [
		{"id": "ajax"          , "clazz": "AjaxEngine"     },  //异步请求引擎
		{"id": "element"       , "clazz": "Element"        },  //DOM元素操作
	//{"id": "xpq"           , "clazz": "XPathQuery"     },  //xpath选择器
		{"id": "animation"     , "clazz": "AnimationEngine"},  //动画引擎
		{"id": "eventManager"  , "clazz": "EventManager"   },  //事件管理
		{"id": "gestureManager", "clazz": "GestureManager" },  //手势管理
		{"id": "cloudapi"      , "clazz": "CloudApi"       }   //手机本地扩展
	];
	this._init = function(){
		_super._init.call(this);
		this._debug = false;    //是否调试程序(会提示错误的assert断言)
		this._offline = false;  //是否离线
		this._build = false;    //是否构建成单文件运行方式

		//浏览器环境下在可能有的接口
		this._win = null;     //运行时环境所在的 window 对象
		this._doc = null;     //document对象
		this._head = null;
		this._domScript = null;
		this.ie = false;      //是否IE浏览器
		this.ff = false;      //是否FireFox
		this.ns = false;      //是否Netscape
		this.opera = false;   //是否Opera
		this.safari = false;  //是否Safari
		this.chrome = false;  //是否谷歌浏览器
		this.moz = false;     //是否Mozilla系列浏览器
		this.ie5 = false;     //是否IE5
		this.ie55 = false;    //是否IE5.5
		this.ie6 = false;     //是否IE6
		this.ie7 = false;     //是否IE7
		this.ie8 = false;     //是否IE8
		this.ff1 = false;     //是否FF1
		this.ff2 = false;     //是否FF2
		this.ff3 = false;     //是否FF3
		this.max = false;     //是否Maxthon
		this.tt = false;      //是否TencentTraveler
		this._platform = "";

		this._config = {};     //框架全局配置信息
		this._conf = {
			"debug"      : false, //是否调试程序(会提示错误的assert断言)
			"core_shield": true,  //是否启用内核防护罩
			"use_console": false, //是否创建调试面板组件
			"use_shell"  : false  //是否创建模拟的手机界面外壳
		};
		this._pathRoot = "";   //框架加载的相对于lib的根目录
		this._pathLib = "";    //lib,tpl库文件目录
		this._pathCss = "";    //css文件目录
		this._pathImg = "";    //图片文件目录

		this._contextList = {};      //上下文环境对象列表
		this._pluginManager = null;  //插件管理者
		this._appManager = null;     //应用管理者
		this._workspace = null;      //工作区
		this._debugPane = null;      //调试面板
		this._zIndex = 0;
		this._tempDiv = null;
		this._testDiv = null;
		this._tpls = {};             //模板库集合

		//this._plugins = {};        //插件列表
		this._ajax = null;           //异步请求引擎
		this._element = null;        //DOM元素管理者
		//this._xpq = null;          //XPathQuery
		this._animation = null;      //动画引擎
		this._task = null;           //任务管理者
		this._eventManager = null;   //事件管理者
		this._gestureManager = null; //手势管理者

		this._win = window;
		this._doc = this._win.document;
		this._checkBrowser();
	};
	this.init = function(){
		this._build = !!window.__build__;
		//from iScroll
		//Is translate3d compatible?
		this.has3d = ("WebKitCSSMatrix" in window && "m11" in new WebKitCSSMatrix());
		//Device sniffing
		this.isIthing = (/iphone|ipad/gi).test(window.navigator.appVersion);
		this.is = {
			"Desktop": true,
			"iOS"    : false
		};
		this.isTouch = ("ontouchstart" in window);
		this.desktopCompatibility = true;
		//Event sniffing
		this.START_EVENT = this.isTouch ? "touchstart" : "mousedown";
		this.MOVE_EVENT = this.isTouch ? "touchmove" : "mousemove";
		this.END_EVENT = this.isTouch ? "touchend" : "mouseup";
		//Translate3d helper
		this.translateOpen = "translate" + (this.has3d ? "3d(" : "(");
		this.translateClose = this.has3d ? ",0)" : ")";
		this.uid = 0;  //Unique ID
		var _this = this;
		var useragent = [  //顺序很重要
			"ipad",
			"iphone",
			"webos",
			"bada",
			"android",
			"opera",
			"chrome",
			"safari",
			"mozilla",
			"gecko",
			"explorer"
		];
		var ua = window.navigator.userAgent;
		//window.prompt("", ua);
		if(ua){
			/*
			if(/iPhone/.test(ua)){
				this._platform = "iphone";
			}else if(/Android/.test(ua)){
				this._platform = "android";
			}
			*/
			var agent = ua.toLowerCase();
			for(var i = 0, len = useragent.length; i < len; i++){
				if(agent.indexOf(useragent[i]) >= 0){
					this._platform = useragent[i];
					break;
				}
			}
		}

		//获取pathRoot
		this._head = document.getElementsByTagName("head")[0];
		var scripts = document.getElementsByTagName("script");
		for(var i = 0, len = scripts.length; i < len; i++){
			var script = scripts[i];
			if(this._build){
				if(script.getAttribute("pathlib")){
					this._domScript = script;
					break;
				}
			}else{
				var src = script.src;
				var p = src.indexOf("aui.lib.js");
				if(p != -1){
					this._domScript = script;
					this._pathRoot = src.substring(0, p - 4);
					break;
				}
			}
		}
		scripts = null;

		//配置信息
		var keys = [
			"src",
			"pathlib", "pathapp", "pathcss", "pathskin", "pathimg", "pathtpl", "pathplugin",
			"css", "lib", "plugin",
			"conf", "runmode", "skinid", "skin", "codeprovider", "autotest", "action",
			"onstartloading"  //开始加载时执行的代码
		];
		for(var i = 0, len = keys.length; i < len; i++){
			var key = keys[i];
			var value = this._domScript.getAttribute(key);
			this._config[key] = value != null ? value : "";
		}
		var conf = this.parseJson(this._config.conf || "{}");
		if(conf){
			for(var k in conf){
				this._conf[k] = conf[k];
			}
		}
		this._debug = this._conf["debug"];
		this._pathLib = this._config["pathlib"];
		this._pathCss = this._config["pathcss"];
		this._pathImg = this._config["pathimg"];

		this._pluginManager = new PluginManager();
		this._pluginManager.create(this, PLUGINS_CONF_0);
		this._appManager = new AppManager();

		//在onload事件发生之前提前预加载某些库文件
		if(!this._build){
			this.loadResFiles("css", this._config["css"].split(","));
			this.loadResFiles("js", this._config["lib"].split(","));
		}
		/*
		window.onload = function(){
			_this.onLoad();
			/ *
			var app = _this.getActiveApp();
			if(app){
				app.init();
			}else if(window.parent == window){  //只在主窗体中，执行这个逻辑
				//[TODO]
				var libs = _this._domScript.getAttribute("lib").split(",");
				_this.loadLibs(libs, _this, function(){
					var app = _this._appManager.getActiveApp();
					if(app){
						//app.setParams(ev.params);
						app.init();
					}
				});
			}
			window.onresize = function(){
				if(_this._workspace){
					var w = window.document.documentElement.clientWidth;
					var h = window.document.documentElement.clientHeight;
					_this._workspace.resize(w, h);
				}
			};
			* /
			window.onunload = function(){
				_this.dispose();
				window.__runtime__ = null;
				//window.onresize = null;
				window.onload = null;
				window.onunload = null;
			};
			//window.onresize();
		};
		*/
	};
	this.dispose = function(){
		this._appManager.dispose();
		this._appManager = null;
		for(var k in this._tpls){
			delete this._tpls[k];
		}
		//this._config = null;
		if(this._debugPane){
			this._debugPane.dispose();
			this._debugPane = null;
		}
		if(this._workspace){
			this._workspace.dispose();
			this._workspace = null;
		}
		/*
		this._gestureManager = null;
		this._eventManager.dispose();
		this._eventManager = null;
		//this._xpq.dispose();
		//this._xpq = null;
		this._task.dispose();
		this._task = null;
		this._animation.dispose();
		this._animation = null;
		this._element.dispose();
		this._element = null;
		*/
		this._pluginManager.dispose();
		this._pluginManager = null;
		for(var k in this._contextList){
			delete this._contextList[k];
		}
		this._testDiv = null;
		this._tempDiv = null;
		this._domScript = null;
		this._head = null;
		this._doc = null;
		this._win = null;
		_super.dispose.apply(this);
	};
	/*
	 * nav.platform Linux armv71
	 * PC Opera  : Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 8.00
	 * PC FF3pre : Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9b4pre) Gecko/2008022005 Minefield/3.0b4pre (.NET CLR 3.5.30729)
	 * PC Chrome : Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10
	 * PC Safari : Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8
	 *             Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; zh-cn) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
	 * iPhone    : Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; zh-cn) AppleWebkit/533.17.9(KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5
	 *             Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_2_1 like Mac OS X; zh-cn) AppleWebKit/525.18.1(KHTML, like Gecko) Version/3.1.1 Mobile/5H11 Safari/525.20
	 * Android2.2: Mozilla/5.0 (Linux; U; Android 2.2; zh-ch; HTC Desire Build/FRF91) AppleWebkit/533.1(KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
	 */
	/**
	 * 利用正则匹配 window.navigator.userAgent 来获取浏览器的类型
	 * @param {Navigator} nav
	 */
	this.getHostenv = function(nav){
		var ua = nav.userAgent;
		//window.alert(this.forIn(nav).join("\n"));
		//window.prompt("", nav.appVersion);  //ua
		var re = {
		//"opera"  : /Opera\/(\d+(?:\.\d+)+)/,      //Opera/9.10
			"opera"  : /Opera[\/\x20](\d+(?:\.\d+)+)/,  //Opera/9.10,Opera 8.00
			"ie"     : /MSIE\x20(\d+(?:\.\d+)+)/,    //MSIE 6.0
			"ff"     : /Firefox\/(\d+(?:\.\d+)+)/,   //Firefox/2.0.0.2
			"ns"     : /Netscape\/(\d+(?:\.\d+)+)/,  //Netscape/7.0
			"chrome" : /Chrome\/(\d+(?:\.\d+)+)\x20Safari\/(\d+(?:\.\d+)+)/,  //Chrome/0.2.149.27 Safari/525.13
			"safari" : /Version\/(\d+(?:\.\d+)+)\x20Safari\/(\d+(?:\.\d+)+)/, //Version/3.0.3 Safari/522.15.5
			"msafari": /Version\/(\d+(?:\.\d+)+)\x20Mobile(?:\/[0-9A-F]+)?\x20Safari\/(\d+(?:\.\d+)+)/,
			"mf"     : /Minefield\/(\d+(?:\.\d+)+)/  //Minefield/3.0b4pre
		};
		//"Window NT 5.0" win2k
		//"Window NT 5.1" winxp
		var hash_platform = {
			"Win32"    : "win",
			"Windows"  : "win",
			"Mac68K"   : "mac",
			"MacPPC"   : "mac",
			"MacIntel" : "mac",
			"Macintosh": "mac",
			"iPhone"   : "mac",
			"X11"      : "unix"
		};
		var host = {"os":"-","env":"-","ver":"0","compatMode":""};
		if(nav.platform in hash_platform){
			host.os = hash_platform[nav.platform];
		}else if(nav.platform.indexOf("Linux") != -1){
			host.os = "linux";
		}
		for(var k in re){
			var arr = re[k].exec(ua);
			if(arr){  //re[k].test(ua)
				host.env = k == "mf" ? "ff": (k == "msafari" ? "safari" : k);
				host.ver = arr[1];
				host.compatMode = host.env == "ie" && this._doc.compatMode == "BackCompat" ? "BackCompat" : "CSS1Compat";
				if(host.env == "ff" || host.env == "ns"){
					var url = window.location.href;
					if(url.substr(url.length - 4).toLowerCase() == ".xul"){
						host.xul = true;
					}
				}
				break;
			}
		}
		if(host.os == "-" || host.env == "-"){
			window.prompt("[WebRuntime::getHostenv]未知的宿主环境，userAgent:", ua);
		}
		return host;
	};
	/**
	 * 检测浏览器类型
	 */
	this._checkBrowser = function(){
		var nav = this._win.navigator;
		this._host = this.getHostenv(nav);
		this._hostenv = this._host.env;
		this.ie = this._hostenv == "ie";
		this.ff = this._hostenv == "ff";
		this.ns = this._hostenv == "ns";
		this.opera = this._hostenv == "opera";
		this.safari = this._hostenv == "safari";
		this.chrome = this._hostenv == "chrome";
		this.moz = this.ns || this.ff;  //nav.product == "Gecko";
		this.ie6 = nav.userAgent.indexOf("MSIE 6.0") != -1;
		this.ie7 = nav.userAgent.indexOf("MSIE 7.0") != -1;
		this.ff1 = nav.userAgent.indexOf("Firefox/1.0") != -1;
		this.ff2 = nav.userAgent.indexOf("Firefox/2.0") != -1;
		this.max = nav.userAgent.indexOf("Maxthon") != -1;
		this.tt = nav.userAgent.indexOf("TencentTraveler") != -1;
		/*
		if(this.ie && this.max && this.tt){
			this._win.alert(
						"您同时开启了Maxthon和腾讯TT浏览器，两个浏览器"
				+ "\n可能会相互影响导致系统出现一些小问题。"
				+ "\n解决方法：请先打开Maxthon，然后再打开腾讯TT。"
			);
		}
		*/
	};
	/**
	 * 批量加载css和js资源
	 * @param {String} type 资源类型(css|js)
	 * @param {Array} files 资源文件列表
	 * @param {Object} appConf 相关的应用配置
	 */
	this.loadResFiles = function(type, files, appConf){
		for(var i = 0, len = files.length; i < len; i++){
			if(type == "css"){
				this.loadResFile(this._head, type, (appConf ? appConf["pathcss"] : this._pathCss) + files[i]);
			}else{  //js
				this.loadResFile(this._head, type, (appConf ? appConf["pathlib"] : this._pathLib) + files[i] + ".js");
			}
		}
	};
	/**
	 * 加载单个css和js资源
	 * @param {Element} parent HEAD元素
	 * @param {String} type 资源类型(css|js)
	 * @param {String} url 资源地址
	 */
	this.loadResFile = function(parent, type, url){
		var obj;
		switch(type){
		case "css":
			//<link type="text/css" rel="stylesheet" href="res/css/aui.css" />
			obj = document.createElement("link");
			obj.type = "text/css";
			obj.rel = "stylesheet";
			obj.href = url;
			break;
		case "js":
			obj = document.createElement("script");
			obj.type = "text/javascript";
			obj.src = url;
			break;
		}
		parent.appendChild(obj);
	};
	/**
	 * onload事件
	 */
	this.onLoad = function(){
		if(!this.getTplData("aui")){
			this.startTimer(100, this, "onLoad");
			return;
		}
		this._pluginManager.initPlugins(PLUGINS_CONF_1);
		/*
		this._element = new Element();
		this._animation = new AnimationEngine();
		this._task = new TaskSchedule();  //任务调度器
		//this._xpq = new XPathQuery();
		this._eventManager = new EventManager();
		this._gestureManager = new GestureManager();
		this._element.create("element", this);
		this._animation.create("animate", this);
		this._task.create("task", this);
		this._eventManager.create("event", this);
		this._gestureManager.create("gesture", this);
		this._cloudapi = new CloudApi();
		this._cloudapi.create("cloudapi", this);
		*/
		this._workspace = new __context__["Workspace"]();
		this._workspace.create(document.body, this._appManager.getMainApp());

		var conf = this._appManager.getActiveAppConf();
		if(conf){
			function app_init(){
				var app = this._appManager.getActiveApp();
				if(app){
					//app.setParams(ev.params);
					app.init();
				}
				//this.setOffline(this._cloudapi.Device.DeviceStateInfo.isNetworkAvailable() == "false");
			}
			if(!this._build){
				//this.loadTpls(conf.tpl, this, function(){});
				if(conf.css){
					this.loadResFiles("css", conf.css.split(","), conf);
				}
				this.loadLibs(conf.lib.split(","), conf, this, app_init);
			}else{
				app_init.call(this);
			}
		}
	};
	//handleEvent
	this.onOffline = function(ev){
		if(this._appManager){
			this._appManager.fireEvent(ev);
		}
	};
	this.onSuspend = function(ev){
		if(this._thread.suspend()){
			var panel = this._workspace.getModalPanel();
			//panel.setOpacity(0.6);
			//panel.addListener(panel._self, "tap", this, "onTap");
			this._workspace.showModal(null, true);
			if(this._appManager){
				this._appManager.fireEvent(ev);
			}
		}
	};
	this.onResume = function(ev){
		if(this._thread.resume()){
			this._workspace.showModal(null, false);
			var panel = this._workspace.getModalPanel();
			panel.removeListener(panel._self, "tap");
			//panel.setOpacity(0);
			if(this._appManager){
				this._appManager.fireEvent(ev);
			}
		}
	};
	/*
	this.onTap = function(ev){
		CloudAPI.Utility.toast("应用已暂停，请激活云应用");
	};
	this.setConfig = function(v){
		this._config = v;
	};
	*/
	/**
	 * 获取配置信息
	 */
	this.getConfigData = function(key){
		return this._config[key];
	};
	/**
	 * 获取配置信息
	 */
	this.getConfData = function(key){
		return this._conf[key];
	};
	this.getWindow = function(){
		return this._win;
	};
	this.getDocument = function(){
		return this._doc;
	};
	this.getActiveApp = function(){
		return this._appManager.getActiveApp();
	};
	/**
	 * 获取工作区组件
	 */
	this.getWorkspace = function(){
		return this._workspace;
	};
	/**
	 * 获取是否离线状态
	 */
	this.getOffline = function(){
		return this._offline;
	};
	this.setOffline = function(v){
		this._offline = v;
		this.fireEvent({"type": "offline", "offline": v});
	};
	this.setDebugPane = function(v){
		this._debugPane = v;
	};
	/**
	 * 记录一条日志信息
	 */
	this.log = function(str){
		if(this._debugPane){
			if(typeof str == "object" && str !== null){
				try{
					str = JSON.stringify(str);
				}catch(ex){
					str = "" + str;
				}
			}
			this._debugPane.appendLog(str, "log");
		}
		if(console){
			console.log(str);
		}
	};
	/**
	 * 记录一条警告信息
	 */
	this.warning = function(str){
		if(this._debugPane){
			this._debugPane.appendLog(str, "warn");
		}
		if(console){
			console.warn(str);
		}
	};
	/**
	 * 记录一条错误信息
	 */
	this.error = function(str){
		if(this._debugPane){
			this._debugPane.appendLog(str, "err");
		}
		if(this._debug){
			window.alert(str);
		}
		if(console){
			console.error(str);
		}
	};
	/**
	 * 断言
	 */
	this.assert = function(exp, msg){
		if(this._debug && !exp){
			window.alert(msg);
		}
	};
	this.getNextZIndex = function(){
		return ++this._zIndex;
	};
	this.mapLib = function(lib, conf){
		//return "/portal/lib.php?lib=" + lib;
		//return "/apps/CityLife/lib/" + lib + ".lib.js";
		//return "/apps/CityLife/" + lib;
		var p = lib.lastIndexOf(".");
		var ext = p != -1 ? lib.substr(p) : ".lib";  //.lib|.tpl
		var name = p != -1 ? lib.substring(0, p) : lib;
		return (conf ? conf["pathlib"] : this._pathLib) + name + ext + (ext == ".js" ? "" : ".js");
	};
	/**
	 * 加载一个普通的JS文件
	 */
	this.loadScript = function(url, agent, func){
		var loader = new ScriptLoader();
		loader.create(this._task.add(agent, func));
		loader.load([url], "", true);
		loader = null;
	};
	/**
	 * 加载多个普通的JS文件
	 */
	this.loadScripts = function(urls, agent, func){
		var loader = new ScriptLoader();
		loader.create(this._task.add(agent, func));
		loader.load(urls, "", true);
		loader = null;
	};
	/**
	 * 加载一个lib文件
	 */
	this.loadLib = function(lib, agent, func){
		var cbid = this._task.add(agent, func, lib);
		var loader = new ScriptLoader();
		loader.create(cbid);
		loader.load([this.mapLib(lib)], "", true);
		loader = null;
	};
	/**
	 * 批量加载lib文件
	 */
	this.loadLibs = function(libs, conf, agent, func){
		var cbid = this._task.add(agent, func, libs);
		var loader = new ScriptLoader();
		loader.create(cbid);
		for(var i = 0, len = libs.length; i < len; i++){
			libs[i] = this.mapLib(libs[i], conf);
		}
		loader.load(libs, "", true);
		loader = null;
	};
	/**
	 * 创建一个lib上下文环境对象
	 */
	this.createContext = function(name){
		return new LibContext(name);
	};
	/**
	 * 注册一个lib库
	 * 一个Lib配置的结构：{name:"",app:"",libImp:"",cxt:null}
	 * regContext
	 * runtime.createContext("alc")
	 * runtime.createApp("alz.util.alc.AppAlc")
	 * @param {String} name
	 * @param {String} appName
	 * @param {Function} libImp
	 */
	this.regLib = function(name, appName, libImp){
		var cxt = this.createContext(name);
		libImp(cxt);
		this._contextList[name] = cxt;  //注册上下文环境
		if(appName != ""){
			var app = this._appManager.createApp(name, appName);
			cxt.application =
			cxt.__context__.application = app;  //绑定到lib上下文环境中
		}
	};
	/**
	 * 注册一个应用
	 * @param {String} name 应用的唯一标识名
	 * @param {Object} conf 应用相关的配置信息
	 */
	this.regApp = function(name, conf){
		this._appManager.regApp(name, conf);
	};
	/**
	 * 创建一个应用
	 * @param {String} name 应用标识名
	 * @param {String} className 应用类的类名
	 * @param {Object} params 传递给应用的参数
	 * @return {Application}
	 */
	this.createApp = function(name, className, params){
		return this._appManager.createApp(name, className, params);
	};
	/**
	 * 注册一个模板库
	 * @param {String} name 模板库的唯一标识名
	 * @param {Object} tplData 模板库数据
	 */
	this.regTpl = function(name, tplData){
		if(name in this._tpls){
			this.error("[WebRuntime::regTpl]模版库重名name=" + name);
		}
		this._tpls[name] = tplData;
	};
	this.getTplData = function(name){
		return this._tpls[name];
	};
	/**
	 * 注册一个插件
	 * @param {String} name 插件名
	 * @param {String} context 要注册到的目标环境(LibContext)
	 * @param {Function} pluginImp 插件的实现函数
	 */
	this.regPlugin = function(name, context, pluginImp){
	};
	/**
	 * 注册一个Job作业
	 */
	this.regJob = function(name, jobImp){
	};
	/**
	 * 根据一段HTML代码字符串创建一个DOM对象
	 * @param {String} html HTML代码字符串
	 * @return {Element} 新创建的DOM对象
	 */
	this.createDomElement = function(html, exp){
		if(!this._tempDiv){
			this._tempDiv = window.document.createElement("div");
		}
		this._tempDiv.innerHTML = html;
		return this._tempDiv.childNodes[0];
		//return jQuery.find(exp, div)[0];
		/*
		var nodes = div.childNodes;
		for(var i = 0, len = nodes.length; i < len; i++){
			if(nodes[i].className == "main"){
				return div.removeChild(nodes[i]);
			}
		}
		return null;
		*/
	};
	//全局事件处理接口
	this.setCapture = function(el){
		this._eventManager.setCapture(el);
	};
	this.releaseCapture = function(el){
		this._eventManager.releaseCapture(el);
	};
	this.addGlobalListener = function(el, type, agent, func){
		this._eventManager.addListener(el, type, agent, func);
	};
	this.removeGlobalListener = function(el, type, agent){
		if(!this._eventManager){
			this.error("[WebRuntime::removeGlobalListener]runtime._eventManager == null");
		}
		this._eventManager.removeListener(el, type, agent);
	};
	/**
	 * 遍历一个对象，并返回格式化的字符串
	 */
	this.forIn = function(obj){
		if(typeof(obj) == "string") return [obj];  //FF 兼容问题
		var a = [];
		for(var k in obj){
			var v = obj[k];
			var str = k + "=" + (typeof v == "function" ? "[function]" : v);
			if(a.push){  //此时可能不支持 push 方法
				a.push(str);
			}else{
				a[a.length] = str;
			}
		}
		return a;
	};
	/**
	 * 把一个JSON字符串解析为 json 对象，成功返回 json 对象，失败返回 null
	 * @param {String} data [JsonCode]符合 JSON 协议的 js 代码
	 */
	this.parseJson = function(data){
		if(data == "") return null;  //防止空数据报错
		try{
			return eval("(" + data + ")");
		}catch(ex){  //json 解析错误
			this.error("[WebRuntime::parseJson]" + ex.message);
			//if(this._debug){
			//	this.showException(ex, "parse json data error");
			//}
			return null;
		}
	};
	/**
	 * HTML 代码编码方法
	 * @param html {String} 要编码的 HTML 代码字符串
	 */
	this.encodeHTML = function(html){
		if(!html){
			return "";
		}else{
			return html
				.replace(/&/g, "&amp;")
				.replace(/</g, "&lt;")
				.replace(/>/g, "&gt;")
				.replace(/\"/g, "&quot;")
				//.replace(/\'/g, "&apos;")
				.replace(/ /g, "&nbsp;")
				.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;")
				.replace(/\r?\n/g, "<br />");
		}
	};
	/**
	 * HTML 代码解码方法
	 * @param html {String} 要解码的 HTML 代码字符串
	 */
	this.decodeHTML = function(html){
		if(!html){
			return "";
		}else{
			return html
				//.replace(/&#37;/ig, "%")
				.replace(/&nbsp;/ig, " ")
				.replace(/&quot;/ig, "\"")
				//.replace(/&apos;/ig, "\'")
				.replace(/&gt;/ig, ">")
				.replace(/&lt;/ig, "<")
				.replace(/&#(\d{2}|\d{4});/ig, function(_0, _1){
					return String.fromCharCode(_1);
				})
				.replace(/&amp;/ig, "&");
		}
	};
	/**
	 * 把模板格式化为一段HTML字符串片段
	 * @param {String} tpl 模板内容
	 * @param {Object} json 局部变量区
	 * @param {Object} hash 全局变量区
	 */
	this.formatTpl = function(tpl, json, hash){
		hash = hash || {};
		return tpl.replace(/\{\$(\w+)\}/ig, function(_0, _1){
			//return _1 in json ? json[_1] : (hash ? hash[_1] : _0);
			return _1 in hash ? hash[_1] : (_1 in json ? json[_1] : _0);
		});
	};
	/**
	 * @deprecated
	 */
	this.tpl_replace = this.formatTpl;
	/**
	 * 克隆一个脚本对象
	 */
	this.clone = function(obj){
		var o;
		switch(typeof obj){
		case "undefined": break;
		case "string"   : o = "" + obj;break;
		case "number"   : o = 0 + obj;break;
		case "boolean"  : o = obj;break;
		case "object"   :
			if(obj === null){
				o = null;
			}else{
				//因为跨 window 操作，所以不能使用 instanceof 运算符
				if("length" in obj){  //obj instanceof Array
					o = [];
					for(var i = 0, len = obj.length; i < len; i++){
						o.push(this.clone(obj[i]));
					}
				}else{
					o = {};
					for(var k in obj){
						//约定"_"开头的属性不进行克隆操作
						o[k] = k.charAt(0) == "_" ? obj[k] : this.clone(obj[k]);
					}
				}
			}
			break;
		default:
			this.log("[ERROR]clone参数遇到未知的类型");
			o = obj;
			break;
		}
		return o;
	};
	this.toArray = function(arr, start, end){
		return Array.prototype.slice.call(arr, start || 0, end || arr.length);
	};
	this.createDelegate = function(obj, fn, args, appendArgs){
		if(!this.getConfData("core_shield")){
			return function(){
				var ap = Array.prototype;
				var callArgs = args || arguments;
				if(appendArgs === true){
					callArgs = ap.slice.call(arguments, 0);
					callArgs = callArgs.concat(args);
				}else if(typeof appendArgs == "number"){
					callArgs = ap.slice.call(arguments, 0);
					//copy arguments first
					var applyArgs = [appendArgs, 0].concat(args);
					//create method call params
					ap.splice.apply(callArgs, applyArgs);
					//splice them in
				}
				return obj[fn].apply(obj || window, callArgs);
			};
		}else{
			var _this = this;
			return function(){
				var ap = Array.prototype;
				try{
					var callArgs = args || arguments;
					if(appendArgs === true){
						callArgs = ap.slice.call(arguments, 0);
						callArgs = callArgs.concat(args);
					}else if(typeof appendArgs == "number"){
						callArgs = ap.slice.call(arguments, 0);
						//copy arguments first
						var applyArgs = [appendArgs, 0].concat(args);
						//create method call params
						ap.splice.apply(callArgs, applyArgs);
						//splice them in
					}
					return obj[fn].apply(obj || window, callArgs);
				}catch(ex){
					_this.error("[WebRuntime::createDelegate*]" + ex.message);
					_this.getActiveApp().showOperationFailed();  //[TODO]不一定是APP的错误
				}
			};
		}
	};
	this._createTestDiv = function(){
		var obj = this._doc.createElement("div");
		obj.style.position = "absolute";
		obj.style.left = "-2000px";
		obj.style.top = "-2000px";
		//obj.style.font = "8pt tahoma";
		return this._doc.body.appendChild(obj);
	};
	this.getTextSize = function(text, font){
		if(!this._testDiv){
			this._testDiv = this._createTestDiv();
		}
		this._testDiv.style.font = font || "8pt tahoma";
		this._testDiv.innerHTML = this.encodeHTML(text);
		return {
			"w": this._testDiv.offsetWidth,
			"h": this._testDiv.offsetHeight
		};
	};
	/**
	 * 启动一个定时器
	 * @param {Number} msec 启动延迟时间(毫秒)
	 * @param {Object} agent 代理对象
	 * @param {Function|String} func 匿名函数或者代理对象的方法名
	 * @return {Number} 定时器id
	 */
	this.startTimer = function(msec, agent, func){
		return this._thread.startThread(msec, agent, func);
	};
	/**
	 * 启动一个系统级定时器，该定时器不受suspend状态影响
	 */
	this.startSysTimer = function(msec, agent, func){
		return this._thread.startThread(msec, agent, func, true);
	};
	this.stopTimer = function(tid){
		if(tid == 0){
			return false;
		}
		return this._thread.stopThread(tid);
	};
});